package cht;

import static org.junit.Assert.assertTrue;
import robocode.control.events.RoundEndedEvent;
import robocode.control.events.TurnEndedEvent;
import robocode.control.snapshot.IRobotSnapshot;
import robocode.control.testing.RobotTestBed;

/**
 * Test to see whether Narchi moves when hit by a bullet.
 * 
 * @author Terrence Chida
 * 
 */
public class TestNarchiMoveWhenHit extends RobotTestBed {

  boolean hit;
  boolean moved;
  boolean reachedCorner;

  /**
   * Specifies that Walls and Narchi are being matched up in this test.
   * 
   * @return The comma-delimited list of robots in this match.
   */
  @Override
  public String getRobotNames() {
    return "sample.Walls,cht.Narchi";
  }

  /**
   * This test runs for 10 round.
   * 
   * @return The number of rounds.
   */
  @Override
  public int getNumRounds() {
    return 10;
  }

  /**
   * Check at the end of each turn to see if Narchi moved.
   * 
   * @param event Information on the current state of the battle.
   */
  @Override
  public void onTurnEnded(TurnEndedEvent event) {
    // Get a snapshot of where Narchi is at the end of each turn.
    IRobotSnapshot narchi = event.getTurnSnapshot().getRobots()[1];
    double narchiX = narchi.getX();
    double narchiY = narchi.getY();
    final double ROBOT_WIDTH = 40.0;

    // If a corner has been reached, check to see if we ever moved away from it.
    if (this.reachedCorner) {
      // Upper-right
      if (((narchiX < (width - ROBOT_WIDTH)) && (narchiY < (height - ROBOT_WIDTH))) ||
      // Upper-left
          ((narchiX < (width - ROBOT_WIDTH)) && (narchiY > ROBOT_WIDTH)) ||
          // Lower-right
          ((narchiX > ROBOT_WIDTH) && (narchiY < (height - ROBOT_WIDTH))) ||
          // Lower-left
          ((narchiX > ROBOT_WIDTH) && (narchiY > ROBOT_WIDTH))) {
        this.moved = true;
      }
    }
    // Otherwise, if a corner has not been reached yet, check if Narchi is close to a corner.
    else {
          // Upper-right
      if (((narchiX >= (width - ROBOT_WIDTH)) && (narchiY >= (height - ROBOT_WIDTH))) ||
          // Upper-left
          ((narchiX >= (width - ROBOT_WIDTH)) && (narchiY <= ROBOT_WIDTH)) ||
          // Lower-right
          ((narchiX <= ROBOT_WIDTH) && (narchiY >= (height - ROBOT_WIDTH))) ||
          // Lower-left
          ((narchiX <= ROBOT_WIDTH) && (narchiY <= ROBOT_WIDTH))) {
        this.reachedCorner = true;
      }
    }

    // Most likely got hit if energy is less than 50.
    if (narchi.getEnergy() < 50) {
      this.hit = true;
    }

  } // end onTurnEnded()

  /**
   * At the end of each round, make assertions.
   * 
   * @param event Information on the current state of the battle.
   */
  public void onRoundEnded(RoundEndedEvent event) {
    assertTrue("Check if hit.", this.hit);
    assertTrue("Check if reached corner.", this.reachedCorner);
    assertTrue("Check if moved after hit.", this.moved);
  } // end onRoundEnded()

} // end TestNarchiMoveWhenHit
